package com.ddwl.wallet.repository.impl;

import com.ddwl.common.constant.BaseEnum;
import com.ddwl.schema.bo.base.PageBo;
import com.ddwl.schema.bo.wallet.UserCouponBo;
import com.ddwl.wallet.dao.model.UserCoupon;
import com.ddwl.wallet.repository.UserCouponRepositoryAdvance;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.time.Instant;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

public class UserCouponRepositoryImpl implements UserCouponRepositoryAdvance {

    @Autowired
    private MongoTemplate template;

    @Override
    public List<UserCoupon> findByUserIdAndCouponId(String userId, Collection<String> couponIds) {
        Criteria criteria = Criteria.where("userId").is(userId).and("coupon.$id").in(couponIds.stream().map(ObjectId::new).collect(Collectors.toList()))
                .and("status").is(BaseEnum.UseEnum.UN_USE.getCode());
        return template.find(Query.query(criteria), UserCoupon.class);
    }

    @Override
    public Long countByUserIdAndCouponId(String userId, String couponId) {
        Criteria criteria = Criteria.where("userId").is(userId).and("coupon.$id").is(new ObjectId(couponId));
        return template.count(Query.query(criteria), UserCoupon.class);
    }

    @Override
    public List<UserCoupon> findByIds(List<String> userCouponIds) {
        Criteria criteria = Criteria.where("_id").is(userCouponIds.stream().map(ObjectId::new).collect(Collectors.toList()));
        return template.find(Query.query(criteria), UserCoupon.class);
    }

    @Override
    public List<UserCoupon> findByUserId(PageBo<UserCouponBo> pageBo) {
        UserCouponBo param = pageBo.getParam();
        Criteria criteria = Criteria.where("userId").is(param.getUserId());
        if (param.getStatus() != null) {
            criteria.and("status").is(param.getStatus());
        }
        return template.find(Query.query(criteria).with(PageRequest.of(pageBo.getPage() - 1, pageBo.getPageSize(), Sort.by(Sort.Direction.DESC, "_id"))), UserCoupon.class);
    }

    @Override
    public void updateExpire() {
        Criteria criteria = Criteria.where("status").is(BaseEnum.UseEnum.UN_USE.getCode()).and("expireDate").lte(Instant.now());
        template.updateMulti(Query.query(criteria), Update.update("status", BaseEnum.UseEnum.EXPIRED.getCode()), UserCoupon.class);
    }
}
